package com.zmc.lostfound.common.exception;

import cn.hutool.http.HttpStatus;
import com.zmc.lostfound.common.utils.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.io.IOException;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author ZMC
 * @description 全局异常拦截处理器
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(value = {MyException.class})
    public Result myException(MyException e) {
        log.error("\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        log.error("【自定义异常】: {}", e.getMessage(), e);
        log.error("\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        return Result.error(HttpStatus.HTTP_INTERNAL_ERROR, "自定义异常").put("errorInfo", e.getMessage());
    }

    @ExceptionHandler(value = {MethodArgumentNotValidException.class})
    public Result methodArgumentNotValidException(MethodArgumentNotValidException e) {
        BindingResult bindingResult = e.getBindingResult();
        Map<String, String> errorMessageMap = new HashMap<>(bindingResult.getFieldErrorCount());
        bindingResult.getFieldErrors().forEach(item -> errorMessageMap.put(item.getField(), item.getDefaultMessage()));
        log.error("\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        log.error("【参数校验异常】: {}", errorMessageMap.toString(), e);
        log.error("\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        return Result.error(HttpStatus.HTTP_BAD_REQUEST, "参数校验异常").put("errorInfo", errorMessageMap);
    }

    @ExceptionHandler(value = {BindException.class})
    public Result bindExceptionException(BindException e) {
        BindingResult bindingResult = e.getBindingResult();
        Map<String, String> errorMessageMap = new HashMap<>(bindingResult.getFieldErrorCount());
        bindingResult.getFieldErrors().forEach(item -> errorMessageMap.put(item.getField(), item.getDefaultMessage()));
        log.error("\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        log.error("【参数校验异常】: {}", errorMessageMap.toString(), e);
        log.error("\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        return Result.error(HttpStatus.HTTP_BAD_REQUEST, "参数校验异常").put("errorInfo", errorMessageMap);
    }

    @ExceptionHandler(value = {IllegalArgumentException.class})
    public Result illegalArgumentException(IllegalArgumentException e) {
        log.error("\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        log.error("【非法数据异常】: {}", e.toString(), e);
        log.error("\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        return Result.error(HttpStatus.HTTP_INTERNAL_ERROR, "非法数据异常").put("errorInfo", e.getMessage());
    }

    @ExceptionHandler(value = {RuntimeException.class})
    public Result runtimeException(RuntimeException e) {
        log.error("\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        log.error("【运行时异常】: {}", e.getMessage(), e);
        log.error("\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        return Result.error(HttpStatus.HTTP_INTERNAL_ERROR, "运行时异常").put("errorInfo", e.getMessage());
    }

    @ExceptionHandler(value = {IOException.class})
    public Result ioException(IOException e) {
        log.error("\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        log.error("【IO异常】: {}", e.getMessage(), e);
        log.error("\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        return Result.error(HttpStatus.HTTP_INTERNAL_ERROR, "IO异常").put("errorInfo", e.getMessage());
    }

    @ExceptionHandler(value = {SQLException.class})
    public Result sqlException(SQLException e) {
        log.error("\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        log.error("【SQL异常】: {}", e.getMessage(), e);
        log.error("\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        return Result.error(HttpStatus.HTTP_INTERNAL_ERROR, "SQL异常").put("errorInfo", e.getMessage());
    }

    @ExceptionHandler(value = {Throwable.class})
    public Result throwable(Throwable e) {
        log.error("\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        log.error("【未知异常】: {}", e.getMessage(), e);
        log.error("\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        return Result.error(HttpStatus.HTTP_INTERNAL_ERROR, "未知异常").put("errorInfo", e.getMessage());
    }

}